<template>
  <div
      class="formulate-container"
  >
    <el-form
        :model="stateArray"
        status-icon
        ref="ruleForm"
        label-width="100px"
        class="demo-ruleForm"
    >
      <el-form-item
          v-for="state in stateArray"
          :label="state.label" >
        <el-checkbox
            :indeterminate="state.isIndeterminate"
            v-model="state.checkAll"
            @change="handleCheckAllChange(state)"
            border
            size="medium"
        >
          全选
        </el-checkbox>
        <div style="margin:10px auto;"></div>
        <el-checkbox-group v-model="state.checkedOptions" @change="(value)=>{
         handleCheckedOptionsChange(value,state)
      }">
          <el-checkbox
              v-for="option in state.options"
              :label="option"
              :key="option"
          >
            {{option}}
          </el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item  label="文件名">
        <el-input style="width:40%;"  placeholder="请输入模板文件名" v-model="fileName"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button
            @click="handleSubmit"
            type="primary"
            round
            icon="el-icon-download"
        >
          导出
        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script lang="ts">

import {defineComponent, reactive, ref,onMounted} from 'vue'
import exportExcel from "/@/utils/excel"
import {storageLocal} from "/@/utils/storage"
import {errorMessage, successMessage} from '/@/utils/message'
import {getTemplateData} from "/@/api";
import {endLoading, startLoading} from "/@/utils/loading";
export default defineComponent({
  name:'',
  setup(){
    // 定义要素配置数组接口
    interface stateType{
      checkAll:boolean,
      checkedOptions:Array<string>,
      options:Array<string>,
      isIndeterminate:boolean,
      label:string
    }
    // 生成要素配置数组
    const stateArray=ref<Array<stateType>|null>([])
    const fileName=ref<string|null>(null)
    // 页面挂载完成后，渲染数据到视图上
    onMounted(()=>{
        startLoading()
        getData()
    })
    const getData=async ()=>{
        try{
          let data=await getTemplateData()
          // 从浏览器缓存中获取用户选中项，用于回显
          let checkedList=storageLocal.getItem('checkedList')
          // 如果用户之前选择过配置项，将选中项字符串映射成数组，checkedList为二维数组
          // 如果用户没有选择过选项，checkedList为空
          checkedList=checkedList?checkedList.map(item=>item.options.split(',')):null
          // 合并数据和选中项，如果用户选择过选项，则从checkedList中取出对应数组，否则为空数组
          data=(data as unknown as any[]).map((item,index)=>({...item,checkedOptions:checkedList?checkedList[index]:[]}))
          // 渲染数据到视图
          initCheckedList(data)
          endLoading()
        }catch (e){
          console.log(e)
          endLoading()
          errorMessage('网络错误！！！')
        }
    }
    // 初始化选中列表
    const initCheckedList=(data:any)=>{
      (data as unknown as Array<any>).forEach(item=>{
        let isNull=item.checkedOptions.includes("")
        // 如果选中项个数等于总的选项个数，checkAll为true，标志当前要素为全选
        let checkAll=isNull?false:item.checkedOptions.length===item.menuNames.length
        // 如果选中项数组为[""]，则isIndeterminate为false，表示当前要素没有选中项
        // 如果选中项个数大于0并且小于总的选项个数，说明当前要素为部分选中，isIndeterminate为true
        let isIndeterminate=isNull?false:item.checkedOptions.length>0&&item.checkedOptions.length<item.menuNames.length
        const state = reactive<stateType>({
          checkAll,
          checkedOptions: item.checkedOptions,
          options: item.menuNames,
          isIndeterminate,
          label:item.codeTableName
        });
        stateArray.value.push(state)
      })
    }
    // 处理全选操作
    const handleCheckAllChange = (state) => {
         // 当全选框被选中时，让所有子选项被选中，否则，将所有子选项置于未选中状态
         state.checkedOptions = state.checkAll ?state.options : []
         // 移除全选框的部分选中的样式
         state.isIndeterminate = false;
    };
    // 选择项发生改变的处理事件
    const handleCheckedOptionsChange = (value,state) => {
            const checkedCount = value.length;
            // 当选中项的个数等于总的可选项个数，设置全选框为选中
            state.checkAll = checkedCount === state.options.length;
            // 如果选中项个数大于0，并且小于可选项个数，将全选框设置为部分选中
            state.isIndeterminate = checkedCount > 0 && checkedCount < state.options.length;
    };
    // 生成Excel模板文件
    const handleSubmit=()=>{
      let data=[]
      // 根据要素项的个数生成对应Excel的表头和下拉项信息
      stateArray.value.forEach(item=>{
         // 计算当前要素选中项的最大长度
         let length=Math.max.apply(null,item.checkedOptions.map(val=>val.length))
         length=length===0?item.label.length:length
         let options=item.checkedOptions.join(',')
         let dataItem={
           header:{
             header: item.label,
             key: item.label,
             width: (length+25)*1.5
           },
           options,
         }
         // if(item.label==='部门'){
         //   data.push({...dataItem,header:{
         //     ...dataItem.header,
         //       header:'问题产生单位'
         //     }})
         //   data.push({...dataItem,header:{
         //     ...dataItem.header,
         //       header:'整改责任部门'
         //     }})
         // }else{
           data.push(dataItem)
         // }
      })
      // 提示用户下载成功
      successMessage('下载模板成功！')
      // 暂存用户选中项，用于回显用户上次选中的选项
      storageLocal.setItem('checkedList',data)
      // 创建exportExcel实例，下载Excel
      new exportExcel(data,fileName.value)
    }
    return {
      stateArray,
      handleCheckAllChange,
      handleCheckedOptionsChange,
      handleSubmit,
      fileName
    };
  }
})


</script>

<style lang='scss' scoped>
.formulate-container{
  width:100%;
  position: relative;
  padding:20px 0;
  z-index:-1;
}
</style>
